home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / xgrab.lha / xgrab / grabst / token.c < prev    next >
C/C++ Source or Header  |  1990-03-06  |  7KB  |  356 lines

  1. /**
  2.    GRAB Graph Layout and Browser System
  3.  
  4.    Copyright (c) 1989, Tera Computer Company
  5.  **/
  6.  
  7.   /**
  8.      token.c is a scanner, specialized for two uses:  reading graph
  9.      input files, and reading predicate files.
  10.      The difference manifests itself in two places:  the graph files don't
  11.      care about reserved words, and the graph files don't care about special
  12.      characters in strings.  So, when reading graph files, get_next_token
  13.      should be invoked with both boolean arguments FALSE, and when reading
  14.      predicate files, both arguments should be TRUE.
  15.    **/
  16. #include <ctype.h>
  17. #include <stdio.h>
  18.  
  19. #include "attribute.h"
  20. #include "digraph.h"
  21. #include "token.h"
  22.  
  23.   /* reserved words */
  24. char *reserved_wd[NUM_RESERVED] = 
  25. {
  26.     "and",
  27.     "or",
  28.     "not",
  29.     "if",
  30.     "then",
  31.     "elsif",
  32.     "else",
  33.     "endif",
  34.     "break",
  35.     "continue",
  36.     "set",
  37.     "coalesce",
  38.     "expand",
  39.     "hide",
  40.     "display",
  41.     "focus",
  42.     "source",
  43.     "sink",
  44.     "in",
  45.     "out",
  46.     "parents",
  47.     "children",
  48.     "ancestors",
  49.     "descendants",
  50.     "shape",
  51.     "brush",
  52.     "color",
  53.     "displayed",
  54.     "node",
  55.     "edge",
  56.     "coalescer"
  57. };
  58.  
  59. static char lastc;    /* the last character we read.  We need one character
  60.                of lookahead, and rather than pushing it back
  61.                on the stream, we just keep it around. */
  62. char char_val;        /* character value for illegal characters */
  63. char string_val[MAXBUFFER];   /* string value for strings and quoted strings */
  64. FILE *readfile;        /* input file */
  65.  
  66. TOKEN token_val();
  67.  
  68. init_reader(rfile)
  69. FILE *rfile;
  70. {
  71.     readfile = rfile;
  72.     lastc = ' ';
  73. }
  74.  
  75. TOKEN get_next_token(reserved, str_restricted)
  76. BOOL reserved;        /* if not TRUE, treat reserved words as strings */
  77. BOOL str_restricted;    /* if TRUE, strings cannot contain special characters */
  78. {
  79.     char_val = '\0';
  80.     string_val[0] = '\0';
  81.  
  82.     while (lastc != EOF && whitespace(lastc))
  83.       /* skip whitespace (tabs and spaces) */
  84.     {
  85.     lastc = getc(readfile);
  86.     }
  87.  
  88.     if (lastc == EOF)          /* eof */
  89.     {
  90.     return EOF_TOKEN;
  91.     }
  92.     else if (lastc == '\n')     /* newline */
  93.     {
  94.     lastc = ' ';             /* common idiom:  if we didn't use lookahead,
  95.                       set lastc to a space, which will not affect
  96.                    the scanner when it is next invoked */
  97.     return NEWLINE_TOKEN;
  98.     }
  99.     else if (!isprint(lastc))     /* illegal character */
  100.     {
  101.     char_val = lastc;
  102.     lastc = ' ';
  103.     return ILLEGAL_CHAR_TOKEN;
  104.     }
  105.     else if (!endchar(lastc) && lastc != '\"' &&
  106.          (!special(lastc) || (!str_restricted)))
  107.       /* read a string */
  108.     {
  109.     read_tstring(string_val, readfile, MAXBUFFER, str_restricted);
  110.  
  111.     if (!reserved)
  112.       /* don't care about reserved words */
  113.     {
  114.         return STRING_TOKEN;
  115.     }
  116.     else
  117.     {
  118.          return token_val(string_val);
  119.     }
  120.     }
  121.     else 
  122.       /* special character (we hope) */
  123.     {
  124.     TOKEN t;
  125.  
  126.     switch (lastc)
  127.     {
  128.         case '=':
  129.             t = EQUAL_TOKEN;
  130.         break;
  131.         case '.':
  132.             t = PERIOD_TOKEN;
  133.         break;
  134.         case '(':
  135.             t = OPENPAREN_TOKEN;
  136.         break;
  137.         case ')':
  138.             t = CLOSEPAREN_TOKEN;
  139.         break;
  140.         case ';':
  141.             t = SEMICOLON_TOKEN;
  142.         break;
  143.         case '\"':
  144.         read_quoted_string(string_val, readfile, MAXBUFFER);
  145.         return QSTRING_TOKEN;
  146.         default:
  147.                 char_val = lastc;
  148.         t = ILLEGAL_START_TOKEN;
  149.         break;
  150.     }
  151.  
  152.     lastc = ' ';
  153.     return t;
  154.     }
  155. }
  156.  
  157. read_quoted_string (s, readfile, limit)
  158. char s[];
  159. FILE *readfile;
  160. int limit;
  161.   /**
  162.      we've read a quotation mark, now read a quoted string from readfile.  
  163.      limit is the length of s
  164.    **/
  165. {
  166.     int i = 0;
  167.  
  168.     if (limit <= 1)
  169.     {
  170.     fprintf(stderr, "read_quoted_string:  limit %d too small\n", limit);
  171.     return;
  172.     }
  173.  
  174.     while ((lastc = getc(readfile)) != EOF && 
  175.        (whitespace(lastc) || isprint(lastc)) && lastc != '\n')
  176.     {
  177.     if (lastc == '\"')
  178.       /* end of string */
  179.     {
  180.         s[i] = '\0';
  181.         lastc = ' ';
  182.         return;
  183.     }
  184.     else if (lastc == '\\')
  185.       /* special character marker */
  186.     {
  187.         if ((lastc = getc(readfile)) == EOF || !isprint(lastc))
  188.         {
  189.             char_val = lastc;
  190.         print_bad_char(
  191.           "read_quoted_string:  Aborted due to illegal character");
  192.         s[i++] = '\\';
  193.         s[i] = '\0';
  194.         return;
  195.         }
  196.         else
  197.         {
  198.         s[i++] = lastc;
  199.         }
  200.     }
  201.     else
  202.       /* normal character */
  203.     {
  204.         s[i++] = lastc;
  205.     }
  206.  
  207.     if (i == limit - 1)
  208.     {
  209.         fprintf(stderr, "quoted string length limit reached\n");
  210.         s[i] = '\0';
  211.  
  212.           /* check if the string was just finished, anyway */
  213.         if ((lastc = getc(readfile)) == '\"')
  214.         {
  215.         lastc = ' ';
  216.         }
  217.  
  218.         return;
  219.     }
  220.     } 
  221.  
  222.     char_val = lastc;
  223.     print_bad_char("read_quoted_string:  Aborted due to illegal character");
  224.     s[i] = '\0';
  225.     return;
  226. }
  227.  
  228. read_tstring (s, readfile, limit, str_restricted)
  229. char s[];
  230. FILE *readfile;
  231. int limit;
  232. BOOL str_restricted;        /* restricted forms of strings */
  233.   /**
  234.      read a text string from readfile.  limit is the length of s.
  235.      if str_restricted is true, special characters aren't allowed in
  236.      the string 
  237.    **/
  238. {
  239.     int i = 0;
  240.  
  241.     if (limit <= 1)
  242.     {
  243.     fprintf(stderr, "read_tstring:  limit %d too small\n", limit);
  244.     return;
  245.     }
  246.  
  247.     do
  248.     {
  249.     s[i++] = lastc;
  250.  
  251.     if (i == limit - 1)
  252.     {
  253.         fprintf(stderr, "string length limit reached\n");
  254.         break;
  255.     }
  256.  
  257.     lastc = getc(readfile);
  258.     } while (!endchar(lastc) && (!special(lastc) || !str_restricted));
  259.  
  260.     s[i] = '\0';
  261. }
  262.  
  263. TOKEN token_val(s)
  264. char *s;
  265.   /**
  266.      if s is a reserved word, return token value of s.  Else, return the
  267.      token for a string.
  268.    **/
  269. {
  270.     int i;
  271.  
  272.     for (i = 0; i < NUM_RESERVED; i++)
  273.     {
  274.         if (!strcmp(s, reserved_wd[i]))
  275.         {
  276.          return ((TOKEN) (i + (int) FIRST_RESERVED_TOKEN));
  277.     }
  278.     }
  279.  
  280.     return STRING_TOKEN;
  281. }
  282.  
  283. print_token(t, nl)
  284. TOKEN t;
  285. BOOL nl;    /* print a newline or not? */
  286.   /* print a text version of t, followed by a newline if nl is TRUE */
  287. {
  288.     if ((int) t >= (int) FIRST_RESERVED_TOKEN && 
  289.     (int) t - (int) FIRST_RESERVED_TOKEN < NUM_RESERVED)
  290.     {
  291.     fprintf(stderr, "reserved \`%s\'", 
  292.         reserved_wd[(int) t - (int) FIRST_RESERVED_TOKEN]);
  293.     }
  294.     else
  295.     {
  296.         switch(t)
  297.         {
  298.             case EOF_TOKEN:
  299.         fprintf(stderr, "eof");
  300.         break;
  301.             case ILLEGAL_CHAR_TOKEN:
  302.         print_bad_char("illegal char");
  303.         break;
  304.             case ILLEGAL_START_TOKEN:
  305.         print_bad_char("illegal start");
  306.         break;
  307.             case STRING_TOKEN:
  308.             fprintf(stderr, "string \`%s\'", string_val);
  309.             break;
  310.             case QSTRING_TOKEN:
  311.         fprintf(stderr, "quoted string \`%s\'", string_val);
  312.         break;
  313.             case NEWLINE_TOKEN:
  314.         fprintf(stderr, "newline");
  315.         break;
  316.             case EQUAL_TOKEN:
  317.         fprintf(stderr, "equal");
  318.         break;
  319.             case PERIOD_TOKEN:
  320.         fprintf(stderr, "period");
  321.         break;
  322.             case OPENPAREN_TOKEN:
  323.         fprintf(stderr, "open paren");
  324.             break;
  325.             case CLOSEPAREN_TOKEN:
  326.         fprintf(stderr, "close paren");
  327.         break;
  328.             case SEMICOLON_TOKEN:
  329.         fprintf(stderr, "semicolon");
  330.         break;
  331.         default:
  332.         fprintf(stderr, "illegal token %d", t);
  333.         break;
  334.     }
  335.     }
  336.  
  337.     if (nl)
  338.     {
  339.     fprintf(stderr, "\n");
  340.     }
  341. }
  342.  
  343. print_bad_char(s)
  344. char *s;
  345.   /* print an illegal character in a pseudo-readable form */
  346. {
  347.     if (isprint(char_val))
  348.     {
  349.         fprintf (stderr, "%s: \`%c\'\n", s, char_val);
  350.     }
  351.     else
  352.     {
  353.         fprintf (stderr, "%s: %.3o\n", s, char_val);
  354.     }
  355. }
  356.